home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume21 / coda / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-04-08  |  42.6 KB

  1. Subject:  v21i086:  File distribution alternative to rdist, Part03/03
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 72edbc40 a1f4390d a164fdd4 1e4b62b8
  5.  
  6. Submitted-by: Rich Salz <rsalz@bbn.com>
  7. Posting-number: Volume 21, Issue 86
  8. Archive-name: coda/part03
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 3 (of 3)."
  17. # Contents:  COPYING client.c coda.1
  18. # Wrapped by rsalz@litchi.bbn.com on Mon Apr  9 16:49:04 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'COPYING' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'COPYING'\"
  22. else
  23. echo shar: Extracting \"'COPYING'\" \(9934 characters\)
  24. sed "s/^X//" >'COPYING' <<'END_OF_FILE'
  25. X            GNU GENERAL PUBLIC LICENSE
  26. X             Version 1, February 1989
  27. X
  28. X Copyright (C) 1989 Free Software Foundation, Inc.
  29. X                    675 Mass Ave, Cambridge, MA 02139, USA
  30. X Everyone is permitted to copy and distribute verbatim copies
  31. X of this license document, but changing it is not allowed.
  32. X
  33. X                Preamble
  34. X
  35. X  The license agreements of most software companies try to keep users
  36. Xat the mercy of those companies.  By contrast, our General Public
  37. XLicense is intended to guarantee your freedom to share and change free
  38. Xsoftware--to make sure the software is free for all its users.  The
  39. XGeneral Public License applies to the Free Software Foundation's
  40. Xsoftware and to any other program whose authors commit to using it.
  41. XYou can use it for your programs, too.
  42. X
  43. X  When we speak of free software, we are referring to freedom, not
  44. Xprice.  Specifically, the General Public License is designed to make
  45. Xsure that you have the freedom to give away or sell copies of free
  46. Xsoftware, that you receive source code or can get it if you want it,
  47. Xthat you can change the software or use pieces of it in new free
  48. Xprograms; and that you know you can do these things.
  49. X
  50. X  To protect your rights, we need to make restrictions that forbid
  51. Xanyone to deny you these rights or to ask you to surrender the rights.
  52. XThese restrictions translate to certain responsibilities for you if you
  53. Xdistribute copies of the software, or if you modify it.
  54. X
  55. X  For example, if you distribute copies of a such a program, whether
  56. Xgratis or for a fee, you must give the recipients all the rights that
  57. Xyou have.  You must make sure that they, too, receive or can get the
  58. Xsource code.  And you must tell them their rights.
  59. X
  60. X  We protect your rights with two steps: (1) copyright the software, and
  61. X(2) offer you this license which gives you legal permission to copy,
  62. Xdistribute and/or modify the software.
  63. X
  64. X  Also, for each author's protection and ours, we want to make certain
  65. Xthat everyone understands that there is no warranty for this free
  66. Xsoftware.  If the software is modified by someone else and passed on, we
  67. Xwant its recipients to know that what they have is not the original, so
  68. Xthat any problems introduced by others will not reflect on the original
  69. Xauthors' reputations.
  70. X
  71. X  The precise terms and conditions for copying, distribution and
  72. Xmodification follow.
  73. X
  74. X            GNU GENERAL PUBLIC LICENSE
  75. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  76. X
  77. X  0. This License Agreement applies to any program or other work which
  78. Xcontains a notice placed by the copyright holder saying it may be
  79. Xdistributed under the terms of this General Public License.  The
  80. X"Program", below, refers to any such program or work, and a "work based
  81. Xon the Program" means either the Program or any work containing the
  82. XProgram or a portion of it, either verbatim or with modifications.  Each
  83. Xlicensee is addressed as "you".
  84. X
  85. X  1. You may copy and distribute verbatim copies of the Program's source
  86. Xcode as you receive it, in any medium, provided that you conspicuously and
  87. Xappropriately publish on each copy an appropriate copyright notice and
  88. Xdisclaimer of warranty; keep intact all the notices that refer to this
  89. XGeneral Public License and to the absence of any warranty; and give any
  90. Xother recipients of the Program a copy of this General Public License
  91. Xalong with the Program.  You may charge a fee for the physical act of
  92. Xtransferring a copy.
  93. X
  94. X  2. You may modify your copy or copies of the Program or any portion of
  95. Xit, and copy and distribute such modifications under the terms of Paragraph
  96. X1 above, provided that you also do the following:
  97. X
  98. X    a) cause the modified files to carry prominent notices stating that
  99. X    you changed the files and the date of any change; and
  100. X
  101. X    b) cause the whole of any work that you distribute or publish, that
  102. X    in whole or in part contains the Program or any part thereof, either
  103. X    with or without modifications, to be licensed at no charge to all
  104. X    third parties under the terms of this General Public License (except
  105. X    that you may choose to grant warranty protection to some or all
  106. X    third parties, at your option).
  107. X
  108. X    c) If the modified program normally reads commands interactively when
  109. X    run, you must cause it, when started running for such interactive use
  110. X    in the simplest and most usual way, to print or display an
  111. X    announcement including an appropriate copyright notice and a notice
  112. X    that there is no warranty (or else, saying that you provide a
  113. X    warranty) and that users may redistribute the program under these
  114. X    conditions, and telling the user how to view a copy of this General
  115. X    Public License.
  116. X
  117. X    d) You may charge a fee for the physical act of transferring a
  118. X    copy, and you may at your option offer warranty protection in
  119. X    exchange for a fee.
  120. X
  121. XMere aggregation of another independent work with the Program (or its
  122. Xderivative) on a volume of a storage or distribution medium does not bring
  123. Xthe other work under the scope of these terms.
  124. X
  125. X  3. You may copy and distribute the Program (or a portion or derivative of
  126. Xit, under Paragraph 2) in object code or executable form under the terms of
  127. XParagraphs 1 and 2 above provided that you also do one of the following:
  128. X
  129. X    a) accompany it with the complete corresponding machine-readable
  130. X    source code, which must be distributed under the terms of
  131. X    Paragraphs 1 and 2 above; or,
  132. X
  133. X    b) accompany it with a written offer, valid for at least three
  134. X    years, to give any third party free (except for a nominal charge
  135. X    for the cost of distribution) a complete machine-readable copy of the
  136. X    corresponding source code, to be distributed under the terms of
  137. X    Paragraphs 1 and 2 above; or,
  138. X
  139. X    c) accompany it with the information you received as to where the
  140. X    corresponding source code may be obtained.  (This alternative is
  141. X    allowed only for noncommercial distribution and only if you
  142. X    received the program in object code or executable form alone.)
  143. X
  144. XSource code for a work means the preferred form of the work for making
  145. Xmodifications to it.  For an executable file, complete source code means
  146. Xall the source code for all modules it contains; but, as a special
  147. Xexception, it need not include source code for modules which are standard
  148. Xlibraries that accompany the operating system on which the executable
  149. Xfile runs, or for standard header files or definitions files that
  150. Xaccompany that operating system.
  151. X
  152. X  4. You may not copy, modify, sublicense, distribute or transfer the
  153. XProgram except as expressly provided under this General Public License.
  154. XAny attempt otherwise to copy, modify, sublicense, distribute or transfer
  155. Xthe Program is void, and will automatically terminate your rights to use
  156. Xthe Program under this License.  However, parties who have received
  157. Xcopies, or rights to use copies, from you under this General Public
  158. XLicense will not have their licenses terminated so long as such parties
  159. Xremain in full compliance.
  160. X
  161. X  5. By copying, distributing or modifying the Program (or any work based
  162. Xon the Program) you indicate your acceptance of this license to do so,
  163. Xand all its terms and conditions.
  164. X
  165. X  6. Each time you redistribute the Program (or any work based on the
  166. XProgram), the recipient automatically receives a license from the original
  167. Xlicensor to copy, distribute or modify the Program subject to these
  168. Xterms and conditions.  You may not impose any further restrictions on the
  169. Xrecipients' exercise of the rights granted herein.
  170. X
  171. X  7. The Free Software Foundation may publish revised and/or new versions
  172. Xof the General Public License from time to time.  Such new versions will
  173. Xbe similar in spirit to the present version, but may differ in detail to
  174. Xaddress new problems or concerns.
  175. X
  176. XEach version is given a distinguishing version number.  If the Program
  177. Xspecifies a version number of the license which applies to it and "any
  178. Xlater version", you have the option of following the terms and conditions
  179. Xeither of that version or of any later version published by the Free
  180. XSoftware Foundation.  If the Program does not specify a version number of
  181. Xthe license, you may choose any version ever published by the Free Software
  182. XFoundation.
  183. X
  184. X  8. If you wish to incorporate parts of the Program into other free
  185. Xprograms whose distribution conditions are different, write to the author
  186. Xto ask for permission.  For software which is copyrighted by the Free
  187. XSoftware Foundation, write to the Free Software Foundation; we sometimes
  188. Xmake exceptions for this.  Our decision will be guided by the two goals
  189. Xof preserving the free status of all derivatives of our free software and
  190. Xof promoting the sharing and reuse of software generally.
  191. X
  192. X                NO WARRANTY
  193. X
  194. X  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  195. XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  196. XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  197. XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  198. XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  199. XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  200. XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  201. XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  202. XREPAIR OR CORRECTION.
  203. X
  204. X  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  205. XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  206. XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  207. XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  208. XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  209. XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  210. XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  211. XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  212. XPOSSIBILITY OF SUCH DAMAGES.
  213. X
  214. X             END OF TERMS AND CONDITIONS
  215. END_OF_FILE
  216. if test 9934 -ne `wc -c <'COPYING'`; then
  217.     echo shar: \"'COPYING'\" unpacked with wrong size!
  218. fi
  219. # end of 'COPYING'
  220. fi
  221. if test -f 'client.c' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'client.c'\"
  223. else
  224. echo shar: Extracting \"'client.c'\" \(15213 characters\)
  225. sed "s/^X//" >'client.c' <<'END_OF_FILE'
  226. X/*
  227. X**  Copyright 1989 BBN Systems and Technologies Corporation.
  228. X**  All Rights Reserved.
  229. X**  This is free software, and may be distributed under the terms of the
  230. X**  GNU Public License; see the file COPYING for more details.
  231. X**
  232. X**  Main code for CODA client.
  233. X*/
  234. X#define MAINLINE
  235. X#include "client.h"
  236. X#ifndef    VMS
  237. X#include <sys/types.h>
  238. X#include <sys/stat.h>
  239. X#else
  240. X#include <types.h>
  241. X#include <stat.h>
  242. X#endif    /* VMS */
  243. X#ifdef    RCSID
  244. Xstatic char RCS[] =
  245. X    "$Header: client.c,v 2.0 90/04/09 15:34:23 rsalz Exp $";
  246. X#endif    /* RCSID */
  247. X
  248. X
  249. X/*
  250. X**  A whole mess of global variables.
  251. X*/
  252. XSTATIC char    ACK[] = "ACK-";        /* Header if command was OK    */
  253. XSTATIC char    DAT[] = "DAT ITEM ";    /* Data file for from command    */
  254. XSTATIC char    NAK[] = "NAK-";        /* Header if it wasn't        */
  255. XSTATIC char    **Lines;        /* Lines read from server    */
  256. XSTATIC char    *Directory;        /* Where sources reside        */
  257. XSTATIC char    *Filename;        /* File for server to read    */
  258. XSTATIC char    *Root;            /* Remote root directory    */
  259. XSTATIC char    *ServerHost;        /* Host server is on        */
  260. XSTATIC char    *UserName;        /* Remote user name        */
  261. XSTATIC char    *UserPass;        /* Remote user password        */
  262. XSTATIC int    MaxLines;        /* Number of lines allocated    */
  263. XSTATIC BOOL    Noaction;        /* Just say what's outdated?    */
  264. XSTATIC int    NumLines;        /* Number of lines used        */
  265. XSTATIC int    Port = PORTNUMBER;    /* Port server is listening    */
  266. XSTATIC int    Verbose;        /* Tell what we're doing?    */
  267. XSTATIC BOOL    ChangeOwner;        /* Try to give away files?    */
  268. XSTATIC BOOL    SlowMode;        /* Do byte comparisons?        */
  269. XSTATIC BOOL    YoungerMode;        /* Can client have newer files?    */
  270. X
  271. X
  272. X
  273. X/*
  274. X**  Print an error message and exit.
  275. X*/
  276. Xvoid
  277. XFatal(p)
  278. X    char    *p;
  279. X{
  280. X    (void)fprintf(stderr, "Coda fatal error:\n\t%s\n", p);
  281. X    exit(EXITERR);
  282. X    /* NOTREACHED */
  283. X}
  284. X
  285. X
  286. X/*
  287. X**  Get a line from the server; if it's a NAK, quit.
  288. X*/
  289. XSTATIC void
  290. XQuitOnNack()
  291. X{
  292. X    char    buff[SIZE];
  293. X
  294. X    if (!SRVget(buff, sizeof buff))
  295. X    Fatal("Server did not reply");
  296. X    if (strncmp(buff, ACK, sizeof ACK - 1) == 0)
  297. X    return;
  298. X    if (strncmp(buff, NAK, sizeof NAK - 1) == 0)
  299. X    Fatal(&buff[sizeof NAK - 1]);
  300. X    (void)fprintf(stderr, "Bad from server:\n\t%s\n", buff);
  301. X    Fatal("Protocol error");
  302. X}
  303. X
  304. X
  305. X/*
  306. X**  Print a warning if user wants to see them.
  307. X*/
  308. XSTATIC void
  309. XCant(Always, Action, Name)
  310. X    BOOL    Always;
  311. X    char    *Action;
  312. X    char    *Name;
  313. X{
  314. X    char    buff[SIZE];
  315. X    int        e;
  316. X
  317. X    if (Always || Verbose > 2) {
  318. X    e = errno;
  319. X    (void)sprintf(buff, "Can't %s %s", Action, Name);
  320. X    errno = e;
  321. X    perror(buff);
  322. X    }
  323. X}
  324. X
  325. X
  326. X
  327. X/*
  328. X**  Set the mode, ownership, etc., on an item to be what they should be.
  329. X*/
  330. XSTATIC void
  331. XSetStuff(Name, Mode, Uid, Gid, Time)
  332. X    char    *Name;
  333. X    int        Mode;
  334. X    int        Uid;
  335. X    int        Gid;
  336. X    long    Time;
  337. X{
  338. X    struct stat     Sb;
  339. X#ifdef    ATTsysv
  340. X    struct utime_t {
  341. X    time_t    x;
  342. X    time_t    y;
  343. X    } t, *vec = &t;
  344. X#else
  345. X    time_t     vec[2];
  346. X#endif    /* ATTsysv */
  347. X
  348. X    /* Get current status. */
  349. X    if (stat(Name, &Sb) < 0) {
  350. X    Cant(TRUE, "stat", Name);
  351. X    return;
  352. X    }
  353. X
  354. X    /* Fix up the permissions on files. */
  355. X    if ((Sb.st_mode & 0777) != Mode) {
  356. X    if (chmod(Name, Mode) < 0)
  357. X        Cant(FALSE, "chmod", Name);
  358. X    else if (Verbose > 1)
  359. X        (void)printf("chmod 0%o %s\n", Mode, Name);
  360. X    }
  361. X
  362. X    /* Fix up the modication time. */
  363. X    if (Sb.st_mtime != Time) {
  364. X#ifdef    ATTsysv
  365. X    t.x = t.y = Time;
  366. X#else
  367. X    vec[0] = vec[1] = Time;
  368. X#endif    /* ATTsysv */
  369. X    if (utime(Name, vec) < 0)
  370. X        Cant(FALSE, "set time", Name);
  371. X    else if (Verbose > 1)
  372. X        (void)printf("settime %ld %s\n", (long)Time, Name);
  373. X    }
  374. X
  375. X    /* Fix up the owner. */
  376. X    if (ChangeOwner && (Sb.st_uid != Uid || Sb.st_gid != Gid)) {
  377. X    if (chown(Name, Uid, Gid) < 0)
  378. X        Cant(FALSE, "chown", Name);
  379. X    else if (Verbose > 1)
  380. X        (void)printf("chown %d chgrp %d %s\n", Uid, Gid, Name);
  381. X    }
  382. X}
  383. X
  384. X
  385. X/*
  386. X**  Do what's necessary to create a directory.
  387. X*/
  388. XSTATIC void
  389. XDoDir(Name, Uid, Gid, Mode, Time)
  390. X    char    *Name;
  391. X    int        Uid;
  392. X    int        Gid;
  393. X    int        Mode;
  394. X    long    Time;
  395. X{
  396. X    struct stat    Sb;
  397. X#ifdef    VMS
  398. X    char    buff[SIZE];
  399. X#endif    /* VMS */
  400. X
  401. X#ifdef    VMS
  402. X    (void)sprintf(buff, "%s.dir", Name);
  403. X    Name = buff;
  404. X#endif    /* VMS */
  405. X
  406. X    /* If directory doesn't exist, create it. */
  407. X    if (stat(Name, &Sb) < 0) {
  408. X    if (Verbose > 0 || Noaction) {
  409. X        (void)printf("mkdir %s\n", Name);
  410. X        if (Noaction)
  411. X        return;
  412. X    }
  413. X    if (mkdir(Name, Mode) < 0)
  414. X        Cant(TRUE, "mkdir", Name);
  415. X    }
  416. X
  417. X    /* Set the other bits. */
  418. X    if (!Noaction)
  419. X    SetStuff(Name, Mode, Uid, Gid, Time);
  420. X}
  421. X
  422. X
  423. X
  424. X/*
  425. X**  Compare two files, if they're different, move the second onto
  426. X**  the first.
  427. X*/
  428. XSTATIC void
  429. XGetFile(Name, Size, KnowItsWrong)
  430. X    char        *Name;
  431. X    REGISTER long    Size;
  432. X    BOOL        KnowItsWrong;
  433. X{
  434. X    REGISTER FILE    *F;
  435. X    REGISTER FILE    *Old;
  436. X    REGISTER char    *p;
  437. X    REGISTER int    c;
  438. X    REGISTER int     c2;
  439. X    char        buff[SIZE];
  440. X    char        temp[SIZE];
  441. X
  442. X    if (!KnowItsWrong && Verbose > 4)
  443. X    (void)printf("Checking %s\n", Name);
  444. X
  445. X    /* Make a temporary filename in the same directory. */
  446. X    (void)strcpy(temp, Name);
  447. X    if (p = strrchr(temp, '/'))
  448. X    p++;
  449. X    else
  450. X    p = temp;
  451. X    (void)strcpy(p, "codaXXXXXX");
  452. X    (void)mktemp(p);
  453. X
  454. X    if ((F = fopen(temp, "w")) == NULL) {
  455. X    Cant(TRUE, "fopen", temp);
  456. X    return;
  457. X    }
  458. X
  459. X    /* Tell the server to send us the file. */
  460. X    (void)sprintf(buff, "SEND %s\n", Name);
  461. X    SRVput(buff);
  462. X    if (!SRVget(buff, sizeof buff)
  463. X     || strncmp(buff, NAK, sizeof NAK - 1) == 0) {
  464. X    Cant(TRUE, "start to read", temp);
  465. X    (void)fclose(F);
  466. X    (void)unlink(temp);
  467. X    return;
  468. X    }
  469. X
  470. X    /* Read it from the server. */
  471. X    while (--Size >= 0) {
  472. X    c = SRVcget();
  473. X    (void)putc(c, F);
  474. X    }
  475. X    (void)fclose(F);
  476. X    QuitOnNack();
  477. X
  478. X    /* If we know it's wrong, just move it. */
  479. X    if (KnowItsWrong) {
  480. X    (void)unlink(Name);
  481. X    if (rename(temp, Name) < 0)
  482. X        Cant(TRUE, "rename to", Name);
  483. X    (void)sprintf(buff, "MESG took %s\n", Name);
  484. X    SRVput(buff);
  485. X    QuitOnNack();
  486. X    return;
  487. X    }
  488. X
  489. X    /* Open both old and new files. */
  490. X    if ((F = fopen(temp, "r")) == NULL) {
  491. X    Cant(TRUE, "reopen", temp);
  492. X    return;
  493. X    }
  494. X    if ((Old = fopen(Name, "r")) == NULL) {
  495. X    Cant(TRUE, "fopen", Name);
  496. X    (void)fclose(F);
  497. X    return;
  498. X    }
  499. X
  500. X    /* Do byte-for-byte comparisons. */
  501. X    while ((c = getc(F)) == (c2 = getc(Old)))
  502. X    if (c == EOF)
  503. X        break;
  504. X    (void)fclose(F);
  505. X    (void)fclose(Old);
  506. X
  507. X    /* Different? */
  508. X    if (c != c2) {
  509. X    if (Verbose || Noaction) {
  510. X        (void)printf("Update %s\n", Name);
  511. X        if (Noaction) {
  512. X        (void)unlink(temp);
  513. X        return;
  514. X        }
  515. X    }
  516. X    (void)unlink(Name);
  517. X    if (rename(temp, Name) < 0)
  518. X        Cant(TRUE, "rename to", Name);
  519. X    (void)sprintf(buff, "MESG took %s\n", Name);
  520. X    }
  521. X    else
  522. X    (void)sprintf(buff, "MESG ignore %s\n", Name);
  523. X    SRVput(buff);
  524. X    QuitOnNack();
  525. X    (void)unlink(temp);
  526. X}
  527. X
  528. X
  529. X/*
  530. X**  Do what's necessary to create a file.
  531. X*/
  532. XSTATIC void
  533. XDoFile(Name, Uid, Gid, Mode, Time, Size)
  534. X    char        *Name;
  535. X    int            Uid;
  536. X    int            Gid;
  537. X    int            Mode;
  538. X    long        Time;
  539. X    long        Size;
  540. X{
  541. X    struct stat        Sb;
  542. X
  543. X    if (stat(Name, &Sb) < 0 || Sb.st_size != Size) {
  544. X    /* File doesn't exist or size is wrong; get it. */
  545. X    if (YoungerMode && Sb.st_mtime > Time) {
  546. X        (void)printf("Younger %s\n", Name);
  547. X        return;
  548. X    }
  549. X    if (Verbose || Noaction) {
  550. X        (void)printf("Update %s\n", Name);
  551. X        if (Noaction)
  552. X        return;
  553. X    }
  554. X    GetFile(Name, Size, TRUE);
  555. X    }
  556. X    else {
  557. X    if (YoungerMode && Sb.st_mtime > Time) {
  558. X        (void)printf("Younger %s\n", Name);
  559. X        return;
  560. X    }
  561. X    if (SlowMode || Sb.st_mtime != Time)
  562. X        /* Slow mode or the times are different; get and check. */
  563. X        GetFile(Name, Size, FALSE);
  564. X    }
  565. X
  566. X    /* Set the other bits. */
  567. X    if (!Noaction)
  568. X    SetStuff(Name, Mode, Uid, Gid, Time);
  569. X}
  570. X
  571. X
  572. X/*
  573. X**  Read the list of files from the server, than parse them.
  574. X*/
  575. XSTATIC void
  576. XParseListResult()
  577. X{
  578. X    REGISTER char    **L;
  579. X    REGISTER char    **Lend;
  580. X    REGISTER char    *p;
  581. X    char        buff[SIZE];
  582. X    char        *Name;
  583. X    int            Uid;
  584. X    int            Gid;
  585. X    long        Size;
  586. X    long        Time;
  587. X    int            Mode;
  588. X    int            What;
  589. X
  590. X    /* Read lines from server. */
  591. X    for (NumLines = 0; SRVget(buff, sizeof buff); ) {
  592. X    /* Check for end of list or a bad line. */
  593. X    if (strncmp(buff, NAK, sizeof NAK - 1) == 0) {
  594. X        (void)printf("%s\n", &buff[sizeof NAK - 1]);
  595. X        return;
  596. X    }
  597. X    if (strncmp(buff, ACK, sizeof ACK - 1) == 0) {
  598. X        (void)printf("%s\n", &buff[sizeof ACK - 1]);
  599. X        break;
  600. X    }
  601. X    if (strncmp(buff, DAT, sizeof DAT - 1)) {
  602. X        (void)fprintf(stderr, "Bogus line from the server:\n\t%s\n", buff);
  603. X        continue;
  604. X    }
  605. X
  606. X    /* Need more room for this line? */
  607. X    if (NumLines == MaxLines - 1) {
  608. X        MaxLines += LINES_DELTA;
  609. X        Lines = GROW(Lines, char*, MaxLines);
  610. X    }
  611. X    Lines[NumLines++] = COPY(&buff[sizeof DAT - 1]);
  612. X    }
  613. X
  614. X    /* Now loop over what we got and parse it. */
  615. X    for (L = Lines, Lend = &Lines[NumLines]; L < Lend; L++) {
  616. X    /* Set defaults to show the stuff is bad. */
  617. X    Name = NULL;
  618. X    Uid = -1;
  619. X    Gid = -1;
  620. X    Size = -1;
  621. X    Time = -1;
  622. X    Mode = -1;
  623. X    What = -1;
  624. X    for (p = strcpy(buff, *L); *p; ) {
  625. X        switch (*p) {
  626. X        default:
  627. X        (void)fprintf(stderr, "Bad field from server:\n\t%s\n", *L);
  628. X        break;
  629. X        case 'N':
  630. X        Name = &p[2];
  631. X        break;
  632. X        case 'W':
  633. X        if (p[2] == 'd' || p[2] == 'f')
  634. X            What = p[2];
  635. X        break;
  636. X        case 'U':
  637. X        Uid = atoi(&p[2]);
  638. X        break;
  639. X        case 'G':
  640. X        Gid = atoi(&p[2]);
  641. X        break;
  642. X        case 'M':
  643. X        Mode = atoi(&p[2]);
  644. X        break;
  645. X        case 'S':
  646. X        Size = atol(&p[2]);
  647. X        break;
  648. X        case 'T':
  649. X        Time = atol(&p[2]);
  650. X        break;
  651. X        }
  652. X
  653. X        /* Move to next field. */
  654. X        while (*p && !WHITE(*p))
  655. X        p++;
  656. X        if (*p)
  657. X        for (*p++ = '\0'; *p && WHITE(*p); )
  658. X            p++;
  659. X    }
  660. X
  661. X    /* Got everything? */
  662. X    if (What < 0 || Mode < 0 || Gid < 0 || Size < 0 || Time < 0
  663. X#ifdef    NOBODY
  664. X     || (Uid < 0 && Uid != NOBODY)
  665. X#else
  666. X     || Uid < 0
  667. X#endif    /* NOBODY */
  668. X     || Name == NULL)
  669. X        (void)fprintf(stderr, "Badly formed line:\n\t%s\n", *L);
  670. X    else if (What == 'd')
  671. X        DoDir(Name, Uid, Gid, Mode, Time);
  672. X    else
  673. X        DoFile(Name, Uid, Gid, Mode, Time, Size);
  674. X    }
  675. X}
  676. X
  677. X
  678. X
  679. X/*
  680. X**  Scan a word for yes or no.
  681. X*/
  682. XSTATIC int
  683. XGetYesOrNo(p, where, flag)
  684. X    char    *p;
  685. X    char    *where;
  686. X    char    flag;
  687. X{
  688. X    char    buff[SIZE];
  689. X
  690. X    switch (*p++) {
  691. X    case 'Y': case 'y':
  692. X    if (p[0] == '\0')
  693. X        return TRUE;
  694. X    if ((p[1] == 'E' || p[1] == 'e')
  695. X     && (p[2] == 'S' || p[2] == 's')
  696. X     && p[3] == '\0')
  697. X    break;
  698. X    case 'N': case 'n':
  699. X    if (p[0] == '\0')
  700. X        return TRUE;
  701. X    if ((p[1] == 'O' || p[1] == 'o')
  702. X     && p[2] == '\0')
  703. X        return TRUE;
  704. X    break;
  705. X    }
  706. X    (void)sprintf(buff, "Expecting one of [YyNn] %s for '%c' flag", where, flag);
  707. X    Fatal(buff);
  708. X    /* NOTREACHED */
  709. X}
  710. X
  711. X
  712. X/*
  713. X**  Skip past the current word and any whitespace that follows it.
  714. X*/
  715. XSTATIC char *
  716. XSkip(p)
  717. X    char    *p;
  718. X{
  719. X    while (*p && !WHITE(*p))
  720. X    p++;
  721. X    while (*p && WHITE(*p))
  722. X    p++;
  723. X    return p;
  724. X}
  725. X
  726. X
  727. X/*
  728. X**  Read the init file.
  729. X*/
  730. XSTATIC void
  731. XReadInitFile()
  732. X{
  733. X    static char    Where[] = "in init file";
  734. X    FILE    *F;
  735. X    char    *p;
  736. X    char    buff[SIZE];
  737. X
  738. X    /* Get the filename, open the file. */
  739. X    if ((p = getenv("CODA")) == NULL || (F = fopen(p, "r")) == NULL) {
  740. X#ifdef    VMS
  741. X    if ((F = fopen(CODA_INIT, "r")) == NULL)
  742. X        return;
  743. X#else
  744. X    if ((p = getenv("HOME")) == NULL)
  745. X        return;
  746. X    (void)sprintf(buff, CODA_INIT, p);
  747. X    if ((F = fopen(buff, "r")) == NULL)
  748. X        return;
  749. X#endif    /* VMS */
  750. X    }
  751. X
  752. X    while (fgets(buff, sizeof buff, F)) {
  753. X    /* Skip blank and comment lines. */
  754. X    if (p = strchr(buff, '\n'))
  755. X        *p = '\0';
  756. X    if (buff[0] == '\0' || buff[0] == '#')
  757. X        continue;
  758. X
  759. X    if (strncmp(buff, "dir", 3) == 0) {
  760. X        p = Skip(buff);
  761. X        Directory = COPY(p);
  762. X    }
  763. X    else if (strncmp(buff, "file", 4) == 0) {
  764. X        p = Skip(buff);
  765. X        Filename = COPY(p);
  766. X    }
  767. X    else if (strncmp(buff, "host", 4) == 0) {
  768. X        p = Skip(buff);
  769. X        ServerHost = COPY(p);
  770. X    }
  771. X    else if (strncmp(buff, "owner", 5) == 0) {
  772. X        p = Skip(buff);
  773. X        ChangeOwner = GetYesOrNo(p, Where, 'o');
  774. X    }
  775. X    else if (strncmp(buff, "pass", 4) == 0) {
  776. X        p = Skip(buff);
  777. X        UserPass = COPY(p);
  778. X    }
  779. X    else if (strncmp(buff, "port", 4) == 0) {
  780. X        p = Skip(buff);
  781. X        Port = atoi(p);
  782. X    }
  783. X    else if (strncmp(buff, "root", 4) == 0) {
  784. X        p = Skip(buff);
  785. X        Root = COPY(p);
  786. X    }
  787. X    else if (strncmp(buff, "slow", 4) == 0) {
  788. X        p = Skip(buff);
  789. X        SlowMode = GetYesOrNo(p, Where, 's');
  790. X    }
  791. X    else if (strncmp(buff, "user", 4) == 0) {
  792. X        p = Skip(buff);
  793. X        UserName = COPY(p);
  794. X    }
  795. X    else if (strncmp(buff, "verb", 4) == 0) {
  796. X        p = Skip(buff);
  797. X        Verbose = atoi(p);
  798. X    }
  799. X    else if (strncmp(buff, "young", 5) == 0) {
  800. X        p = Skip(buff);
  801. X        YoungerMode = GetYesOrNo(p, Where, 'y');
  802. X    }
  803. X    else {
  804. X        (void)fprintf(stderr, "Unknown line:\n\t%s\n", buff);
  805. X        Fatal("Bad init file");
  806. X    }
  807. X    }
  808. X    (void)fclose(F);
  809. X}
  810. X
  811. X
  812. Xmain(ac, av)
  813. X    int        ac;
  814. X    char    *av[];
  815. X{
  816. X    static char    Where[] = "on command line";
  817. X    char    buff[SIZE];
  818. X    char    pass[SIZE];
  819. X    int        i;
  820. X
  821. X    /* Get defaults from environment if possible. */
  822. X    ReadInitFile();
  823. X    (void)umask(0);
  824. X
  825. X    /* Parse JCL. */
  826. X    while ((i = getopt(ac, av, "cd:f:h:no:p:r:s:tu:v:x:y:")) != EOF)
  827. X    switch (i) {
  828. X    default:
  829. X        Fatal("Bad calling sequence");
  830. X        /* NOTREACHED */
  831. X    case 'c':
  832. X        Copyright();
  833. X        exit(EXITOK);
  834. X        /* NOTREACHED */
  835. X    case 'd':
  836. X        Directory = optarg;
  837. X        break;
  838. X    case 'f':
  839. X        Filename = optarg;
  840. X        break;
  841. X    case 'h':
  842. X        ServerHost = optarg;
  843. X        break;
  844. X    case 'n':
  845. X        Noaction = TRUE;
  846. X        break;
  847. X    case 'o':
  848. X        ChangeOwner = GetYesOrNo(optarg, Where, 'o');
  849. X        break;
  850. X    case 'p':
  851. X        Port = atoi(optarg);
  852. X        break;
  853. X    case 'r':
  854. X        Root = optarg;
  855. X        break;
  856. X    case 's':
  857. X        SlowMode = GetYesOrNo(optarg, Where, 's');
  858. X        break;
  859. X    case 't':
  860. X        SRVtrace = TRUE;
  861. X        break;
  862. X    case 'u':
  863. X        UserName = optarg;
  864. X        break;
  865. X    case 'v':
  866. X        Verbose = atoi(optarg);
  867. X        break;
  868. X    case 'x':
  869. X        UserPass = optarg;
  870. X        break;
  871. X    case 'y':
  872. X        YoungerMode = GetYesOrNo(optarg, Where, 'y');
  873. X        break;
  874. X    }
  875. X    av += optind;
  876. X
  877. X    /* Got everything we need? */
  878. X    if (ServerHost == NULL)
  879. X    Fatal("Need name of server host");
  880. X    if (Port == 0)
  881. X    Fatal("Need port to connect to");
  882. X    if (UserName == NULL)
  883. X    Fatal("Need your name on the server machine");
  884. X
  885. X    /* Get passwword. */
  886. X    if (UserPass == NULL) {
  887. X    (void)printf("Enter password:");
  888. X    (void)fflush(stdout);
  889. X    GetPassword(pass, sizeof pass);
  890. X    UserPass = pass;
  891. X    }
  892. X
  893. X    /* Talk to the server */
  894. X    if (!SRVopen(ServerHost, Port))
  895. X    Fatal("Can't open connection to server");
  896. X    QuitOnNack();
  897. X
  898. X    /* Log in. */
  899. X    (void)sprintf(buff, "USER %s %s", UserName, UserPass);
  900. X    SRVput(buff);
  901. X    QuitOnNack();
  902. X
  903. X    /* Tell the server where to go. */
  904. X    if (Directory) {
  905. X    (void)sprintf(buff, "GOTO %s", Directory);
  906. X    SRVput(buff);
  907. X    QuitOnNack();
  908. X    }
  909. X
  910. X    /* Read the file. */
  911. X    if (Filename) {
  912. X    (void)sprintf(buff, "READ %s", Filename);
  913. X    SRVput(buff);
  914. X    }
  915. X    else
  916. X    SRVput("READ");
  917. X    QuitOnNack();
  918. X
  919. X    /* Set the root directory. */
  920. X    if (Root) {
  921. X    (void)sprintf(buff, "ROOT %s", Root);
  922. X    SRVput(buff);
  923. X    QuitOnNack();
  924. X    }
  925. X
  926. X    /* Any other arguments are block names. */
  927. X    if (*av) {
  928. X    /* Get some space. */
  929. X    MaxLines = LINES_DELTA;
  930. X    Lines = NEW(char*, MaxLines);
  931. X    for ( ; *av; av++) {
  932. X        (void)printf("Doing %s...\n", *av);
  933. X        (void)sprintf(buff, "LIST %s", *av);
  934. X        SRVput(buff);
  935. X        ParseListResult();
  936. X    }
  937. X    }
  938. X    else {
  939. X    /* No arguments means do the whole shebang. */
  940. X    MaxLines = LINES_DELTA * 2;
  941. X    Lines = NEW(char*, MaxLines);
  942. X    (void)printf("Working...\n");
  943. X    SRVput("LIST");
  944. X    ParseListResult();
  945. X    }
  946. X
  947. X    /* That's all she wrote. */
  948. X    SRVclose();
  949. X    exit(EXITOK);
  950. X    /* NOTREACHED */
  951. X}
  952. END_OF_FILE
  953. if test 15213 -ne `wc -c <'client.c'`; then
  954.     echo shar: \"'client.c'\" unpacked with wrong size!
  955. fi
  956. # end of 'client.c'
  957. fi
  958. if test -f 'coda.1' -a "${1}" != "-c" ; then 
  959.   echo shar: Will not clobber existing file \"'coda.1'\"
  960. else
  961. echo shar: Extracting \"'coda.1'\" \(14762 characters\)
  962. sed "s/^X//" >'coda.1' <<'END_OF_FILE'
  963. X.TH CODA 1 LOCAL
  964. X.SH NAME
  965. Xcoda \- Code distribution aid
  966. X.SH SYNOPSIS
  967. X.RS
  968. X.ti -.5i
  969. X.B coda
  970. X.na
  971. X[
  972. X.B \-c
  973. X] [
  974. X.BI \-d dir
  975. X] [
  976. X.BI \-r dir
  977. X] [
  978. X.BI \-h host
  979. X] [
  980. X.BI \-p port#
  981. X] [
  982. X.BI \-f file
  983. X] [
  984. X.BI \-u name
  985. X] [
  986. X.BI \-x pass
  987. X] [
  988. X.BI \-s y_or_n
  989. X] [
  990. X.BI \-y y_or_n
  991. X] [
  992. X.BI \-o y_or_n
  993. X] [
  994. X.B \-n
  995. X] [
  996. X.B \-t
  997. X] [
  998. X.B \-v #
  999. X] [
  1000. X.I names...
  1001. X]
  1002. X.ad
  1003. X.RE
  1004. X.SH DESCRIPTION
  1005. X.I Coda
  1006. Xis used to keep source distributions current across a set of machines.
  1007. XIt is not as flexible as
  1008. X.IR rdist (1),
  1009. Xbut it requires less of the client machines because they do not have to be
  1010. Xrunning Unix or the Berkeley networking programs.
  1011. XThe other difference is that when using
  1012. X.IR rdist ,
  1013. Xthe server ``pushes'' files out to the clients, while with
  1014. X.I coda
  1015. Xthe clients ``pull'' files from the server as they need them.
  1016. X.I Coda
  1017. Xwas designed to have a simple client that easily ports to a wide
  1018. Xvariety of systems.
  1019. X.PP
  1020. XThe most common way of using
  1021. X.I coda
  1022. Xis to create a configuration file in your home directory.
  1023. XOn
  1024. X.SM UNIX
  1025. Xsystems, the file is named
  1026. X.I $HOME/.codarc
  1027. Xwhile on
  1028. X.SM VMS
  1029. Xmachines it is named
  1030. X.IR SYS$LOGIN:CODA.DAT .
  1031. XOn either system, to use a different file, set the environment variable
  1032. X.I CODA
  1033. Xto the name of the file.
  1034. XThis is useful to share a common a file among project members.
  1035. XThe config file identifies where the server host is, your name
  1036. X(and password) on the server, and where the Codafile and sources
  1037. Xare to be found.
  1038. X.PP
  1039. XThe config file is a set of lines that make name-value pairs.
  1040. XLines starting with a pound sign are ignored.
  1041. XThe following is a sample configuration file; the field names are
  1042. Xexplained below:
  1043. X.RS
  1044. X.nf
  1045. X.ta \w'#verbose  'u
  1046. X##  Server host and port number
  1047. Xhost    papaya.bbn.com
  1048. Xport    1999
  1049. X##  Our name and password on the server host
  1050. Xuser    rsalz
  1051. Xpass    doubtful
  1052. X##  Directory to start from, name of the file to read
  1053. Xdir    /usr/cronus
  1054. Xfile    src/make_all/Codafile
  1055. X##
  1056. X#root    /nfs/papaya/u1/cronusbuild/cronus
  1057. Xslow    n
  1058. Xverbose    1
  1059. X##  Can client have newer files?  Yes, while porting to it
  1060. Xyounger    y
  1061. X.fi
  1062. X.RE
  1063. X.PP
  1064. XIn addition to using the config file, it is possible to specify the
  1065. Xparameters by using command line flags.
  1066. XAny values set by flags override the values in the config file.
  1067. XThe following tables matches names in the config file to command line flags.
  1068. X.RS
  1069. X.nf
  1070. X.ta \w'younger  'u +\w'Flag    'u
  1071. XFile    Flag    Meaning
  1072. X\l'5i'
  1073. Xhost    \-h    Name of the server host
  1074. Xport    \-p    Port to connect to; default is 1999
  1075. Xuser    \-u    Your login name on the server
  1076. Xpass    \-p    Your password on the server; see below
  1077. Xdir    \-d    Directory for server to change to
  1078. Xfile    \-f    File to read (if not Codafile) in the directory given above
  1079. X    \-n    No action, just report what would be changed
  1080. Xroot    \-r    Path to find files in; overrides what the Codafile declared
  1081. Xslow    \-s    Do byte-for-byte comparisons
  1082. X    \-t    Trace the protocol
  1083. Xverbose    \-v    How much information to show
  1084. Xyounger    \-y    Allow newer files to be on the client
  1085. Xowner    \-o    Retain original ownership
  1086. X.fi
  1087. X.RE
  1088. X.PP
  1089. XIf your password is not listed in the config file, or specified on the
  1090. Xcommand line,
  1091. X.I coda
  1092. Xwill ask you for it.
  1093. XIf you do put your password in the config file, make sure that nobody
  1094. Xelse can read the file!
  1095. X.PP
  1096. XOnce the file has been read, the server will send over a list of
  1097. Xfiles and directories.
  1098. X.I Coda
  1099. Xwill parse this list, and update any files and directories it has to.
  1100. X.PP
  1101. XFor efficiency,
  1102. X.I coda
  1103. Xnormally just checks the sizes of the local and master copy, and will only
  1104. Xupdate the local copy if they are different.
  1105. XIf the modification dates are different,
  1106. X.I coda
  1107. Xwill get a copy of the file and do a byte-for-byte comparison to see if
  1108. Xthe files actually are different.
  1109. XIf the ``\-s'' flag is used,
  1110. X.I coda
  1111. Xwill ignore the time check, and will get every file
  1112. Xand compare it with the local copy.
  1113. X.PP
  1114. XIf you use the ``\-n'' flag,
  1115. X.I coda
  1116. Xwill not do work, but will instead just report what files
  1117. Xand directories are out of date.
  1118. X.PP
  1119. XDuring a port, a client will often have files that have been modified after
  1120. Xthey have been obtained from the server, but before the changes have been
  1121. Xintegrated into the master sources.
  1122. XOn systems where the client's timestamp can be trusted (e.g., not on VMS
  1123. Xbecause there is no equivalent of the
  1124. X.IR utime (2)
  1125. Xcall), the ``\-y'' flag may be used to specify that the client might
  1126. Xhave files that are younger, or more recent, than those on the server.
  1127. XThe default option, ``\-yn'' will cause
  1128. X.I coda
  1129. Xto check if the files are different, and overwrite them, if the timestamps
  1130. Xare different in any way.
  1131. X.PP
  1132. XBy default the person who runs
  1133. X.I coda
  1134. Xwill be the owner of the files.
  1135. XTo make the ownerships match those on the server, use the ``\-oy'' flag.
  1136. XThis is probably more correct in a production environment than when
  1137. Xporting.
  1138. X.PP
  1139. XIf you use the ``\-v'' flag,
  1140. X.I coda
  1141. Xwill give more verbose information about what it is doing.
  1142. XFor example, ``\-v1'' will list all files and directories that have
  1143. Xto be created.
  1144. XIf you use the ``\-v2'' flag,
  1145. X.I coda
  1146. Xwill report when it has to change the ownership or permission on files,
  1147. Xsuch as when a file has the right time and size, but is owned by the
  1148. Xwrong person.
  1149. XSince it is normally not a big problem if the wrong person owns a file,
  1150. Xor if it has the wrong permissions,
  1151. X.I coda
  1152. Xdoes not complain if something cannot be fixed.
  1153. XYou can use the ``\-v3'' flag to see a message whenever the program
  1154. Xcannot set the file mode or ownership.
  1155. XIf you use the ``\-v4'' flag
  1156. X.I coda
  1157. Xwill report on every file as it does the byte-for-byte comparison of slow mode.
  1158. XYou should probably always use either ``\-v1'' or ``\-v3.''
  1159. X.PP
  1160. XTo trace all interactions with the server, use the ``\-t'' flag; this
  1161. Xwill provide output like the following:
  1162. X.RS
  1163. X.nf
  1164. X\fIprompt%\fP coda -d/usr/rsalz -f coda/Codafile -h papaya -u rsalz -x ... -t misc
  1165. X<<<ACK-Hello FIG.BBN.COM; how are you today?
  1166. X>>>USER rsalz ...
  1167. X<<<ACK-Logged in rsalz
  1168. X>>>GOTO /usr/rsalz
  1169. X<<<ACK-Done
  1170. X>>>READ coda/Codafile
  1171. X<<<ACK-Done
  1172. XDoing misc...
  1173. X>>>LIST misc
  1174. X<<<DAT ITEM W=d N=cbin U=-2 G=121 M=511 S=512 T=609796129
  1175. X<<<DAT ITEM W=f N=cbin/dcc U=-2 G=121 M=493 S=150 T=603474106
  1176. X    ...
  1177. X<<<ACK-Found 105 files
  1178. XFound 105 files
  1179. Xmkdir cbin
  1180. XUpdate cbin/dcc
  1181. X    ...
  1182. X>>>QUIT
  1183. X\fIprompt%\fP
  1184. X.fi
  1185. X.RE
  1186. X(Lines without the angle brackets are the
  1187. X.IR coda 's
  1188. Xnormal output.)
  1189. XThis is detailed information and generally nobody but your local
  1190. X.I coda
  1191. Xmaintainer will care.
  1192. X.PP
  1193. XThe ``\-c'' flag prints out copyright and version information.
  1194. X.SH "CODAFILES"
  1195. XThe coda server reads a file to determine what parts of a distribution
  1196. Xget sent to which hosts.
  1197. XThe file is normally named
  1198. X.IR Codafile .
  1199. XThis section explains how to write codafiles, and does not have to
  1200. Xbe read by everyone.
  1201. X.PP
  1202. XBlank lines are ignored, as is anything after a pound sign.
  1203. XWhitespace is not significant.
  1204. XThere are a few keywords, and they appear in bold in the examples
  1205. Xbelow.
  1206. XTo use a keyword as a filename (e.g., if you have a directory named
  1207. X.IR class ),
  1208. Xput it in quotes.
  1209. XIt is also necessary to quote words if they contain any characters
  1210. Xother than letters, numbers, or the characters period, slash, or underscore.
  1211. X.PP
  1212. XThere are four constructs in a Codafile:  parameter definitions,
  1213. Xhost definitions, class definitions, and file definitions or blocks.
  1214. XThey may appear in any order.
  1215. X.PP
  1216. XParameter definitions are a catch-all for miscellaneous parameters.
  1217. XThere are currently three parameters.
  1218. XMost pathnames in a Codafile will be relative paths, the ``root''
  1219. Xis used for any directories or files that do not start with a slash.
  1220. XFor example:
  1221. X.RS
  1222. X\fBdefine\fP \fBroot\fP \fB=\fP /usr/cronus \fB;\fP
  1223. X.RE
  1224. XThis is most useful when the Codafile for a system is not at
  1225. Xthe top of the directory tree, or when it exists in someone's home
  1226. Xdirectory.
  1227. X.PP
  1228. XAt times it is useful to use the same Codafile for several different
  1229. Xsource trees.
  1230. XThe easiest way to do this is to not allow the clients to specify the
  1231. Xdifferent roots.
  1232. XSince this can be a security hole, a Codafile can specify that 
  1233. Xthe root directory specified in the file may not be overridden by the
  1234. Xclient.
  1235. XTo do this, use the following line:
  1236. X.RS
  1237. X\fBdefine\fP \fBrooted\fP \fB=\fP yes \fB;\fP
  1238. X.RE
  1239. XThe value can be any word starting with the letter
  1240. X.IR y .
  1241. XThe default value is \fIno\fP
  1242. X.PP
  1243. XThe final parameter controls whether or not binary files are sent.
  1244. XWhen preparing a list of files, the server can read the first few bytes
  1245. Xto see if a file is an ``a.out'' file, and if so, it will not list it.
  1246. XTo suppress this check, add a line like this:
  1247. X.RS
  1248. X\fBdefine\fP \fBbinaries\fP \fB=\fP yes \fB;\fP
  1249. X.RE
  1250. XThe value can be any word starting with the letter
  1251. X.IR y .
  1252. XThe default value is \fIyes\fP
  1253. X.PP
  1254. XHost definitions are used to name the hosts that are allowed to
  1255. Xreceive the distribution, and to identify the system type.
  1256. XBoth the names and types are arbitrary text strings; host names
  1257. Xare converted to all uppercase.
  1258. XA client's hostname must be defined in the Codafile before the server
  1259. Xwill send any files to it.
  1260. X.RS
  1261. X.nf
  1262. X.ta \w'host  'u +\w'pineapple.bbn.com  'u +\w'=  'u
  1263. X\fBhost\fP    citron.bbn.com    \fB=\fP VMS \fB;\fP
  1264. X\fBhost\fP    pineapple.bbn.com    \fB=\fP ultrix \fB;\fP
  1265. X\fBhost\fP    doe.bbn.com    \fB=\fP sun4 \fB;\fP
  1266. X\fBhost\fP    papaya.bbn.com    \fB=\fP sun3 \fB;\fP
  1267. X.fi
  1268. X.RE
  1269. XIf for some reason the server cannot determine the client's host name,
  1270. Xthen the name
  1271. X.I _ANYHOST
  1272. Xis used.
  1273. X.PP
  1274. XIn order to make the Codafile shorter, hosts are grouped into classes.
  1275. XFor example, it is convenient to be able to say ``give all the Unix
  1276. Xmachines the files in foo.''
  1277. XClasses are defined in two ways, by being named as a system type in a
  1278. Xhost definition, like above, or by appearing in a class definition,
  1279. Xlike this:
  1280. X.RS
  1281. X.nf
  1282. X.DT
  1283. X\fBclass\fP    SUN    \fB=\fP sun3, sun4 \fB;\fP
  1284. X\fBclass\fP    UNIX    \fB=\fP SUN, ultrix \fB;\fP
  1285. X.fi
  1286. X.RE
  1287. XNote that classes can be nested and can contain other classes.
  1288. XIn particular, it is possible to make loops that will tie the server
  1289. Xup in knots.
  1290. XUnlike host names, case is significant in class names.
  1291. XBy convention, classes defined as host types are in lowercase, while
  1292. Xthose defined as class types are in uppercase.
  1293. XThe special built-in class
  1294. X.I _ALL
  1295. Xcontains all hosts except
  1296. X.IR _ANYHOST .
  1297. XA Codafile for a public archive might start off like this:
  1298. X.RS
  1299. X.nf
  1300. X.ta \w'define  'u +\w'_ANYHOST   'u
  1301. X\fBdefine\fP    \fBroot\fP    \fB=\fP /usr/spool/ftp \fB;\fP
  1302. X\fBdefine\fP    \fBbinaries\fP    \fB=\fP no \fB;\fP
  1303. X\fBhost\fP    _ANYHOST    \fB=\fP guest \fB;\fP
  1304. X\fBclass\fP    WORLD    \fB=\fP _ALL, _ANYHOST \fB;\fP
  1305. X.fi
  1306. X.RE
  1307. X.PP
  1308. XThe most important part of a Codafile is the file definitions, or blocks.
  1309. XThese have the following syntax (optional items are shown in square brackets):
  1310. X.RS
  1311. X.nf
  1312. X.DT
  1313. X[ \fBonly_explicitly\fP ] name \fB:\fP class \fB{\fP
  1314. X    item
  1315. X        [ \fBexcept\fP [\fBdirectory\fP] class pattern, ... ; ]
  1316. X        [ \fBexcept\fP [\fBdirectory\fP] class pattern, ... ; ]
  1317. X    item
  1318. X        ...
  1319. X    \fBdirectory\fP item
  1320. X        [ \fBexcept\fP [\fBdirectory\fP] class pattern, ... ; ]
  1321. X\fB}\fP
  1322. X.fi
  1323. X.RE
  1324. XThe name is used by client programs to limit the set of files they
  1325. Xwant to receive, while the class is used by the server to determine
  1326. Xif the client has any access to the block at all.
  1327. XIf a client does not name specific blocks, then all blocks in the file are
  1328. Xexamined.
  1329. XIf a block starts with the \fIonly_explicitly\fP keyword, than it must
  1330. Xbe explicitly named by the client, otherwise it is not listed.
  1331. XThis is useful, for example, when the default is to distribute a complete
  1332. Xsystem without test data.
  1333. X.PP
  1334. XWithin the block, each item names either a file or a directory.
  1335. XIf the item does not start with a slash, then the root is prepended.
  1336. XIf the item is a directory, than the server will walk down all the
  1337. Xfiles and directories beneath the named item.
  1338. XTo name just a directory, put the word \fIdirectory\fP before the
  1339. Xitem name.
  1340. XFor example:
  1341. X.RS
  1342. X.nf
  1343. Xheaders \fB:\fP _ALL \fB{\fP
  1344. X    include
  1345. X    \fBdirectory\fP cetc
  1346. X    cetc/hostfile
  1347. X    cetc/typefile
  1348. X    /etc/motd
  1349. X\fB}\fP
  1350. X.fi
  1351. X.RE
  1352. XThis specifies that all hosts get the directory named
  1353. X.I include
  1354. Xand all files and directories within it.
  1355. XThe next three lines specify that all clients should have the
  1356. X.I cetc
  1357. Xdirectory and the two files
  1358. X.I hostfile
  1359. Xand
  1360. X.I typefile
  1361. Xwithin it.
  1362. XThe actual location of these files on the server depends on the value
  1363. Xof the root parameter.
  1364. XTheir location on the client is relative to the directory from which the
  1365. X.I coda
  1366. Xwas first invoked.
  1367. XThe last line specifies that the motd file
  1368. Xshould exist with the indicated full pathname, regardless of the value
  1369. Xof the root parameter, or where the client is being run from.
  1370. X.PP
  1371. XItems can be given exception lists.
  1372. XException lists are patterns similar to shell wildcards:
  1373. X.RS
  1374. X.nf
  1375. X.ta \w'Character  'u
  1376. XCharacter    Meaning
  1377. X?    Any single character
  1378. X*    Zero or more characters
  1379. X[abc..09]    Any single character inside the brackets
  1380. X    The sequence ``a-z'' can be used to mean ``abcdefghijklmnopqrstuvwxyz''
  1381. X[^a-z]    Any single character not inside the brackets.
  1382. X\ex    The character ``x'' has no special meaning (e.g., \e?)
  1383. X.fi
  1384. X.RE
  1385. XException patterns only match against the last part of the pathname.
  1386. XThat is,
  1387. X.I mgr.c
  1388. Xand not
  1389. X.IR /usr/cronus/src/lib/asynclib/mgr.a .
  1390. XTo match against the whole pathname, precede the pattern with an uparrow.
  1391. XThis can be necessary when you want to exclude a particular file that
  1392. Xhas the same part of name as a directory further up in the source tree.
  1393. X.PP
  1394. XFor example, with the following hierarchy:
  1395. X.RS
  1396. X.nf
  1397. Xclib/commandfile
  1398. Xclib/cronus.a
  1399. Xclib/diamond/fonts/helvetica10.font
  1400. Xclib/diamond/fonts/tv8b.font
  1401. Xclib/diamond/lib.a
  1402. Xclib/diamond/config
  1403. Xclib/editkeysfile
  1404. Xclib/lint/llib-lasync
  1405. Xclib/lint/llib-lasync.ln
  1406. Xclib/lint/llib-lulib
  1407. Xclib/lint/llib-lulib.ln
  1408. Xclib/malloctool.a
  1409. X.fi
  1410. X.RE
  1411. XAnd the following block definition:
  1412. X.RS
  1413. X.nf
  1414. Xlibrary \fB:\fP _ALL {
  1415. X    clib
  1416. X    \fBexcept\fP _ALL "*.a", "*.ln" \fB;\fP
  1417. X    \fBexcept\fP \fBdirectory\fP VMS diamond, lint \fB;\fP
  1418. X}
  1419. X.fi
  1420. X.RE
  1421. XThen, no clients will get the compiled libraries or
  1422. X.IR lint (1)
  1423. Xlibraries,
  1424. Xand VMS clients will not get any files in the lint or diamond directories.
  1425. XAll clients will get the (presumably text) files named
  1426. X.IR commandfile ,
  1427. Xand
  1428. X.IR editkeysfile .
  1429. X.PP
  1430. XWith a good set of classes it is quite easy to tersely specify distributions.
  1431. XThe following example suffices to distribute the major part of the
  1432. XCronus source tree:
  1433. X.RS
  1434. X.nf
  1435. Xsources \fB:\fP _ALL \fB{\fP
  1436. X    src
  1437. X        \fBexcept\fP    VMS    Makefile, "*.sh", "*.s", "llib-l*" \fB;\fP
  1438. X        \fBexcept\fP    UNIX    descrip.mms,  "*.opt", "*.com", "*.mar" \fB;\fP
  1439. X        \fBexcept\fP    _ALL    "*.[oa]", "*.ln" \fB;\fP
  1440. X        \fBexcept\fP    _ALL    a.out, core, foo, tags \fB;\fP
  1441. X\fB}\fP
  1442. X.fi
  1443. X.RE
  1444. X.SH AUTHOR
  1445. XThis program was written by Rich $alz <rsalz@bbn.com>.
  1446. XIt has the following copyright:
  1447. X.RS
  1448. X.nf
  1449. XCopyright 1989 BBN Systems and Technologies Corporation.
  1450. XAll Rights Reserved.
  1451. XThis is free software, and may be distributed under the terms of the
  1452. XGNU Public License; see the file COPYING for more details.
  1453. X
  1454. X$Header: coda.1,v 2.0 90/03/23 15:01:50 rsalz Exp $
  1455. X.fi
  1456. X.RE
  1457. X.SH "SEE ALSO"
  1458. Xcodaserver(8).
  1459. END_OF_FILE
  1460. if test 14762 -ne `wc -c <'coda.1'`; then
  1461.     echo shar: \"'coda.1'\" unpacked with wrong size!
  1462. fi
  1463. # end of 'coda.1'
  1464. fi
  1465. echo shar: End of archive 3 \(of 3\).
  1466. cp /dev/null ark3isdone
  1467. MISSING=""
  1468. for I in 1 2 3 ; do
  1469.     if test ! -f ark${I}isdone ; then
  1470.     MISSING="${MISSING} ${I}"
  1471.     fi
  1472. done
  1473. if test "${MISSING}" = "" ; then
  1474.     echo You have unpacked all 3 archives.
  1475.     rm -f ark[1-9]isdone
  1476. else
  1477.     echo You still need to unpack the following archives:
  1478.     echo "        " ${MISSING}
  1479. fi
  1480. ##  End of shell archive.
  1481. exit 0
  1482. exit 0 # Just in case...
  1483.